package tddd24.ajgallery.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;

import com.google.gwt.core.client.GWT;

import tddd24.ajgallery.server.DatabaseController;

public class ajGalleryServlet extends HttpServlet {

	private static final String sep = File.separator;
	private static final String DB_DIRECTORY = System.getProperty("user.home") + sep + "serverDisk";
	private static final String UPLOAD_DIRECTORY = DB_DIRECTORY + sep + "uploaded";
	private static final String  SCRIPT_PATH = DB_DIRECTORY + sep + "scripts" + sep;
	private static final String  OUTPUT_DIRECTORY = DB_DIRECTORY + sep + "output";
	private static final String DEFAULT_TEMP_DIR = ".";

	private DatabaseController dbContr = new DatabaseController(DB_DIRECTORY);	

	private long currentPic; 
	private long lastPic; 
	
	public ajGalleryServlet() {
		// super(); // Not required, the compiler automatically calls the no-args super constructor.

		dbContr.addExistingFiles(new File(UPLOAD_DIRECTORY));
		currentPic = dbContr.getFirstFileNumber();
		lastPic = dbContr.getLastFileNumber();
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		//your image servlet code here
		resp.setContentType("image/jpeg");
		
		File file = new File(UPLOAD_DIRECTORY, dbContr.getFileData(currentPic)[1]);	

		resp.setContentLength((int)file.length());

		// Open the file and output streams
		FileInputStream in = new FileInputStream(file);
		OutputStream out = resp.getOutputStream();

		// Copy the contents of the file to the output stream
		byte[] buf = new byte[1024];
		int count = 0;
		while ((count = in.read(buf)) >= 0) {
			out.write(buf, 0, count);
		}
		in.close();
		out.close();
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		if(req.getParameter("direction") != null){
			doPut(req, resp);
			return;
		}

		// process only multipart requests
		if (ServletFileUpload.isMultipartContent(req)) {

			File tempDir = getTempDir();
			if (!tempDir.exists()) {
				tempDir.mkdirs();
			}


			File databaseDirectory = new File(DB_DIRECTORY);
			if(! databaseDirectory.exists())
			{
				databaseDirectory.mkdirs();
			}

			File uploadDirectory = new File(UPLOAD_DIRECTORY);
			if(! uploadDirectory.exists())
			{
				uploadDirectory.mkdirs();
			}

			// Create a factory for disk-based file items
			FileItemFactory factory = new DiskFileItemFactory();

			// Create a new file upload handler
			ServletFileUpload upload = new ServletFileUpload(factory);

			// Parse the request
			try {
				List<FileItem> items = upload.parseRequest(req);
				for (FileItem fileItem : items) {
					// process only file upload
					if (fileItem.isFormField()) continue;

					String fileName = fileItem.getName();
					// get only the file name not whole path
					if (fileName != null) {
						fileName = FilenameUtils. getName(fileName);
					}

					File uploadedFile = new File(UPLOAD_DIRECTORY, fileName);
					// dbContr.addFile(uploadedFile) checks if file already exists in database (if so, false is returned).
					if (dbContr.addFile(uploadedFile)) {
						fileItem.write(uploadedFile);
						resp.setStatus(HttpServletResponse.SC_CREATED);

						long fileNumber = dbContr.getLastFileNumber();
						resp.getWriter().print(
								"The file " +  dbContr.getFileData(fileNumber)[1] 
										+ " was uploaded successfully at time: " 
										+ dbContr.getFileData(fileNumber)[2]
												+ ". The file has fileNumber " + fileNumber + ".");

						resp.flushBuffer();

					} else
						throw new IOException("The file already exists in repository.");

				}
			} catch (Exception e) {
				e.printStackTrace();
				resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
						"An error occurred while creating the file : " + e.getMessage());
			}

		} else {
			resp.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE,
					"Request contents type is not supported by the servlet.");
		}
	}

	private File getTempDir() {
		return new File(DEFAULT_TEMP_DIR);
	}


	@Override
	protected void doPut(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		String p = req.getParameter("direction");
		if(p.equals("next")){
			if(dbContr.getNextFileNumber(currentPic) == -1)
				currentPic = dbContr.getFirstFileNumber();
			else
				currentPic = dbContr.getNextFileNumber(currentPic);
			
		} else if(p.equals("previous")){
			if(dbContr.getPrecedingFileNumber(currentPic) == -1)
				currentPic = dbContr.getLastFileNumber();
			else
				currentPic = dbContr.getPrecedingFileNumber(currentPic);
		} 
	}


	//	public void deleteRow (String ID) {}
	//	@Override
	//	public ArrayList<String[]> processInput(String input) {
	//		return new ArrayList<String[]>();
	//	}
	//	public ArrayList<String[]> getData() {
	//		return new ArrayList<String[]>();
	//	}
}
